home *** CD-ROM | disk | FTP | other *** search
-
- Ponizszy tekst ukazal sie w formie artykulu na lamach polskiej edycji
- Magazynu Amiga. Postanowilem jednak dolaczyc go w niezmienionej
- formie takze jako tutorial do najnowszej edycji FlexCata. Przyklady
- do tekstu zalaczone sa w postaci zrodel w jezyku C i znajduja sie
- w katalogu "Sources/C".
-
- Milej lektury ;-)
-
-
- Ponizszy tekst oraz zwiazane z nim przykladowe zrodla nie moga byc
- przedrukowywane ani publikowane w zadnej formie, papierowej badz
- elektronicznej bez zgody autora tekstu.
-
- ©1997-1999 Marcin Orlowski <carlos@amiga.com.pl>
-
-
- ---------------------------------------
-
-
- "Do you arbeit mit printer?"
- czyli Amiga poliglotkâ
-
-
- Mimo, ûe system operacyjny Amigi od dobrych paru lat wspomaga tworzenie
- programów wielkojëzykowych (tzw. zlokalizowanych) to jednak duûy procent
- dostëpnych programów z tych dobrodziejstw, nie wiedzieê czemu, nie
- korzysta...
-
- 1. Sîowem wstëpu
-
- Jak sië w dalszej czëôci przekonasz, decyzja aby napisaê wîasny program
- wielojëzykowy, nie pociga za sobâ ûadnych wiëkszych problemów, za to
- przynosi dodatkowe korzyôci. Wbrew pozorom wiëkszoôê Polaków nie zna
- jëzyka angielskiego w stopniu wystarczajâcym do bezbolesnej pracy z
- programami nim tylko sië posîugujâcymi, podstawowym zaô bîëdem wiëkszoôci
- programistów jest zaîoûenie, ûe kaûdy z uûytkowników dysponuje wiedzâ co
- najmniej takâ jak oni sami. W rzeczywistoôci nawet tak proste zwroty jak
- "Editing Time", "Saved By", "End of text reached", czy "Talk As You Type"
- przysparzajâ wielu problemów (z ciekawszych, niestety autentycznych,
- tîumaczeï: "Edycja czasu", "Zapisz obok", "Wyciâgam zakoïczenia z tekstu"
- oraz "Wymowa wedîug parametrów"). Z resztâ szczególne traktowanie jëzyka
- angielskiego teû nie jest reguîâ - ilu z was uruchamiajâc nawet ciekawie
- zapowiadajâcy sië program, czym prëdzej wybierze "Beenden" widzâê jego
- niemiecko-jëzyczny interfejs uûytkownika?
-
- 2. Reguîy...
-
- ...sâ doôê proste. Wybierasz jëzyk, który bëdzie podstawowym dla Twojego
- programu (w wiëkszoôci przypadków jest to angielski). Nastëpnie zabierasz
- sie do pisania wîaôciwej treôci programu, z tâ drobnâ róûnicâ, ûe wszystkie
- komunikaty programu, które normalnie umieôciîbyô w jego treôci, zastëpujesz
- wywoîaniem odpowiedniej funkcji, zaô same teksty umieszczasz w dodatkowym
- pliku, z którego bëdziesz je w razie potrzeby podczas pracy pobieraî.
-
- 3. Katalogi
-
- Powyûszy mechanizm pozwala na w miarë îatwâ zmianë wersji jëzykowej poprzez
- zastâpienie pliku jego tîumaczeniem, i mogîoby sië wydawaê, ûe najlepszym
- rozwiâzaniem problemu przechowywania tekstów jest uûycie zwykîego pliku
- ASCII. Niestety, najprostsze rozwiâzania nie zawsze sâ nalepsze. Na
- pierwsze problemy natkniemy sië juû przy modyfikacji zawartoôci takiego
- zbioru. Wystarczy niefrasobliwie usunâê jakikolwiek tekst ze ôrodka, bâdú
- zmieniê ich kolejnoôê aby przekonaê sië jak bogatym zasobem przekleïstw
- dysponujâ nasi tîumacze. Przy tym nie mamy ûadnego wpîywu na dîugoôê
- poszczególnych tekstów w pliku, gdyû przy prostocie edycji plików ASCII
- mogâ sië one w niekontrolowany sposób zmieniaê. Po trzecie nie mamy ûadnej
- kontroli nad aktualnoôciâ wersji takiego pliku. Po czwarte zaô, wystarczy
- uruchomiê program korzystajâcy z pliku o dîugoôci 100KB kilka razy
- (pamiëtajmy, ûe od 1995 roku ûyjemy w ôwiecie 32-bitowej wielozadaniowoôci)
- aby zauwaûyê drastyczny spadek iloôci dostëpnej wolnej pamiëci. Po piâte
- zaô zmuszamy uûytkownika do manipulowania plikami, za kaûdym razem gdy
- bëdzie chciaî zmieniê wersjë jëzykowâ.
-
- Lekarstwo na wymienione powyûej bolâczki pojawiîo sië po raz pierwszy w
- wersji 2.05 systemu operacyjnego i nazywa sië locale.library. Biblioteka
- tak wprowadza wîasny sposób obsîugi tekstów, przechowujâc je w pliku zwanym
- katalogiem (od angielskiego "catalog file"). Wykorzystanie tej biblioteki
- pozwoli nam na proste zaimplementowanie obsîugi róûnych jëzyków w naszym
- programie.
-
- Katalog powstaje jako wypadkowa dwóch plików, opisu katalogu (ang.
- "catalog descriptor") oraz jego tîumaczenia (ang. "catalog translation")
- "potraktowanych" odpowiednim programem. Tîumaczenie to jak nazwa wskazuje
- inna wersja jëzykowa tekstów programu i w tym artykule nie bëdziemy sië nim
- zajmowaê. Dokîadniej przyjrzymy sië natomiast opisowi katalogu , bowiem
- plik ten sîuûy takûe do utworzenia domyôlnej (wbudowanej) wersji jëzykowej,
- którâ program nasz bëdzie sië posîugiwaî w przypadku braku jakiegokolwiek
- katalogu. Poniewaû wiëkszoôê z programów sîuûâcych do tworzenia katalogów
- ma dodatkowo moûliwoôê generowania odpowiednich tekstów úródîowych do ich
- obsîugi, wiëc pracë mamy znacznie uîatwionâ. Z dostëpnych obecnie narzëdzi
- dwa sâ godne uwagi. Sâ to programy CatComp oraz FlexCat. CatComp
- znajdowaî sië pierwotnie jedynie w pakiecie dostëpnym dla zarejestrowanych
- developerów Amigi, co znacznie zawëûaîo krâg jego uûytkowników (obecnie
- znaleúê go moûna takûe na pîycie DeveloperCD), natomiast FlexCat jest
- programem darmowym i powszechnie dostëpnym w sieci Internet (Aminet katalog
- dev/misc, stona WWW: http://www.wfmh.pl/amiga/). Wprawdzie oba potrafiâ
- generowaê wspomniany juû kod úródîowy, lecz jedynie FlexCat dziëki
- wykorzystaniu tekstów wzorcowych (patrz dokumentacja programu), obsîuguje
- jëzyki inne niû C (obecnie sâ to Assembler, AmigaE, C++, Modula oraz
- Oberon, zaô w razie potrzeby moûna samemu dodaê obsîugë kaûdego nowego
- jëzyka).
-
- 4. Skîadnia
-
- Kaûdy tekst w pliku opisowym poprzedzony jest odpowiedniâ deklaracjâ w
- formacie:
-
- ETYKIETA (ID/MIN/MAX)
-
- gdzie ETYKIETA to unikalny ciâg znaków identyfikujâcy dany tekst, np.
- MSG_TEXT_2. ID to, równieû unikalny, identyfikator tekstu, zaô MIN i MAX
- to dopuszczalna minimalna i maksymalna dîugoôê tîumaczenia danego tekstu.
- ID, MIN oraz MAX sâ wartoôciami opcjonalnymi i mogâ zostaê pominiëte. W
- przypadku nie podania jawnie wartoôci ID, zostanie ona wygenerowana
- automatycznie, zaô niepodanie MIN czy MAX oznacza brak narzuconych
- ograniczeï (patrz listing #1). Najprostsza forma deklaracji zatem to:
-
- ETYKIETA (//)
-
- Bezpoôrednio pod etykietâ umieszczamy wîaôciwy tekst. Jeôli zajmowaê ma on
- wiëcej niû jednâ linië, kaûdâ z nich koïczymy znakiem "\" (podobnie jak w
- przypadku #define w jëzyku C). W przypadku wykorzystania z sekwencji
- specjalnych jak np. %s, %ld czy '\n', '\t' zarówno FlexCat jak i CatComp
- sprawdzâ ich poprawnoôê oraz ostrzegâ w przypadku uûycia niestandardowych
- sekwencji. Dopuszczalne sâ takûe linie komentarza, które rozpoczyna znak
- ôrednika umieszczony w pierwszej kolumnie.
-
- 5. Funkcje biblioteczne
-
- Uûywanie katalogów nie odbiega wcale do pracy z bibliotekami systemowymi.
- przed ich uûyciem naleûy katalog otworzyê (otwierajâc uprzednio bibliotekë
- locale.library):
-
- struct Catalog *OpenCatalog(Locale, Nazwa, Tag, ...);
-
- gdzie Locale to wskaúnik na strukturë Locale, dla których chcemy dany
- katalog otworzyê. Zazwyczaj podaje sië wartoôê NULL, co powoduje uûycie
- struktury aktualnie uûywanej przez system (a ustawionej przez uûytkownika
- za pomocâ panelu preferencji Locale). Nazwa okreôla fizycznâ nazwë
- uûywanego przez program katalogu. Naleûy podaê jedynie nazwë pliku (np.
- "HelloWorld.catalog"), do której dodana zostanie ôcieûka np.
- "PROGDIR:Catalogs/" + "polski/" (nazwa kolejnego, ustawionego przez
- uûytkownika systemu, preferowanego jëzyka pobrana ze struktury Locale).
- Dodatkowe tagi umoûliwiajâ wymuszenie otwarcia katalogu o konkretnej wersji
- (OC_Version - w odróûnieniu od OpenLibrary(), numer wersji katalogu musi
- byê identyczny z ûâdanym, aby wykonanie funkcji sië powiodîo), czy
- okreôlenie jëzyka (OC_BuiltInLanguage) jaki jest w program wbudowany (w
- naszym przykîadzie jëzyk wbudowany okreôlimy uûywajâc atrybutu #language,
- króry jest rozszerzeniem skîadni wprowadzonym przez FlexCata). Podanie
- NULL oznacza iû program nie posiada wbudowanych tekstów, jednakûe sytuacja
- taka nie jest wskazana, choê moûe byê przydatne w przypadku programów
- majâcych bardzo duûâ bazë komunikatów. Po skoïczonej pracy katalog naleûy
- zamknâê:
-
- void CloseCatalog(struct Catalog *catalog);
-
- W odróûnieniu od wiëkszoôci innych funkcji systemowych, NULL jako wynik
- OpenCatalog() nie oznacza bîëdu, a jedynie fakt nieznalezienia pliku z
- ûâdanâ wersjâ jëzykowâ. NULL jest takûe poprawnym argumentem funkcji
- CloseCatalog().
-
- Poszczególne teksty pobieraê bëdziemy za pomocâ funkcji:
-
- STRPTR GetCatalogStr(struct Catalog *catalog, LONG Numer, STRPTR TekstDomyôlny);
-
- gdzie Numer to ID ûâdanego tekstu, zaô TekstDomyôlny to wskaúnik na tekst
- który uûyty bëdzie gdy ciâg znakow o ûâdanym ID nie zostaî w katalogu
- znaleziony bâdú wskaúnik catalog równy jest NULL (np. z powodu braku
- katalogu). Jako rezultat otrzymamy wskaúnik na interesujâcy nas tekst.
- Pozostaje on waûny do momentu zamkniëcia katalogu i pamiëtaê naleûy, ûe tak
- jak biblioteki czy czcionki, katalog wczytywany jest do pamiëci tylko raz,
- podczas pierwszego otwarcia, zatem ûe tekst na który wskaúnik otrzymaliômy
- jest tylko do odczytu.
-
- 6. Program przykîadowy
-
- Do utworzenia niezbëdnych procedur obsîugi katalogów oraz wersji domyôlnej
- posîuûymy sië w naszym przykîadzie FlexCatem. Po zapisaniu na dysku opisu
- katalogu (listing #1) oraz úródîa wîaôciwego (listing #2), uruchamiamy
- FlexCata:
-
- FlexCat HelloWorld.cd HelloWorld_str.c=AutoC_c.sd
- FlexCat HelloWorld.cd HelloWorld_str.h=AutoC_h.sd
-
- Dodatkowy tekst úródîowy utworzony na podstawie wzorca AutoC wykorzystuje
- bardzo wygodny mechanizm autoinicjalizacji/autoterminacji, który w tym
- przypadku zwalnia nas od rëcznego wywoîywania funkcji
- otwierajâcych/zamykajâcych biblioteki oraz plik katalogu. Jeôli uûywasz
- kompilatora innego niû SAS/C, Dice badú gcc musisz dopisaê wywoîania
- funkcji _STIOpenCatalog() i _STICloseCatalog(), bâdú uûyê innego wzorca.
- Dolâczamy do naszego úródîa wygenerowany plik HelloWorld_str.h aby móc sië
- do tekstów odwoîywaê za pomocâ etykiet, a nastëpnie caîoôê kompilujemy:
-
- SC HelloWorld.c HelloWorld_str.c LINK PROGNAME=HelloWorld
-
- i uruchamiamy. Przykro mi jeôli spodziewaîeô sie w tym miejscu
- fajerwerków. Dopóki nie utworzymy dodatkowych katalogów do programu, to
- wizualnie nie bëdzie sië róûniî od swoich "normalnych" braci. Ale to
- dopiero za miesiâc.
-
- 7. Drobiazgi uîatwiajâce ûycie
-
- Wszystkim którzy tîumaczyê bëdâ Twój program z pewnoôciâ pomoûesz, jeôli
- uwzglëdnisz poniûszych parë "drobiazgów" (a z wîasnego doôwiadczenia wiem
- jak irytujâcy moûe byê fakt ich braku):
-
- * Etykietë kaûdego tekstu rozpoczynaj od przedrostka MSG_. Znacznie
- uîatwia to póúniejszâ aktualizacjë istniejâcych katalogów, gdyû w oparciu
- o przedrostek moûna szybko stworzyê prostâ makrodefinicjë (np. uûywajâc
- CEDa), która skopiuje istniejâce tîumaczenia z poprzedniej edycji.
- Oczywiôcie moûesz uûyê innego przedrostka (byle w identycznego dla wszystkich
- etykiet), jednak utarîo sië aby byî to ciâg "MSG_".
-
- * Unikaj enigmatycznych identyfikatorów. Wprawdzie doskonale wiesz kiedy
- kaûdy z tekstów jest uûywany, ale wiekszoôê tîumaczy zdolnoôci
- jasnowidzenia nie posiada i raczej na pewno nie zgadnie gdzie dany tekst
- wykorzystujesz. Tîumaczenie moûe wtedy byê zrobione na tzw. "oko" i
- nie koniecznie musi wtedy pasowaê do kontekstu caîoôci. Po prostu pisz
- MSG_MAIN_WINDOW_TITLE zamiast MSG_13254 (palce na pewno Cië nie
- rozbolâ).
-
- * Nie uûywaj etykiet w jëzyku polskim (lub jak kto woli pisz po angielsku).
- W poîâczeniu z poprzednim "drobiazgiem" pozwoli to tîumaczowi zorientowaê
- sië w kontekscie uûycia danego tekstu i odpowiednio to przetîumaczyê, w
- przeciwnym razie uraczysz go odpowiednikiem MSG_BEHAGA_NEDTRYCKA_ENTER
-
- * Nie bâdú skâpy. Pamiëtaj ûe w zaleûnoôci od kontekstu tîumacz moûe
- chcieê zastosowaê rózne tîumaczenia tego samego wyrazu czy choêby go
- odmieniê (aby uniknâê îamaïców typu "OKNO/NOWY"). Pozwól mu wiëc na to i
- nie wykorzystuj jednego tekstu do wielu zastosowaï.
-
- * Rzadko kiedy tîumacz ma tyle wolnego czasu (albo ochoty) aby przeîoûyê
- wszystkie teksty za jednym posiedzeniem. Czësto teû chciaîby popracowaê
- chwilë z niedokoïczonym tîumaczeniem (co pozwala wykryê niedokîadnoôci
- czy choêby literówki). I tu napotyka na pewien problem. Poniewaû
- przekîad nie jest skoïczony, pewien procent pól w pliku #?.ct jest pustych.
- Katalog wygenerowany na jego podstawie bëdzie wiëc zawieraî jedynie
- identyfikatory danych tekstów. Pobranie takiego tekstu da nam w rezultacie
- wskaúnik na ciâg znaków o dîugoôci zero i jeôli go uûyjemy zaowocuje to
- nam pustymi gadûetami czy polami menu. Aby temu zaradziê zmodyfikujemy
- nieznacznie wzorzec funkcji GetString() zawarty w pliku AutoC_c.sd
- FlexCata, tak aby w przypadku napotkania pustego ciâgu zwracaî nam tekst
- wbudowany. Zmodyfikowana funkcja wyglâdaê moûe np. tak:
-
- STRPTR GetString(struct FC_Type *fcstr)
- {
- STRPTR defaultstr = fcstr->Str;
- LONG strnum = fcstr->ID;
- STRPTR str;
-
- str = (%b_Catalog ? GetCatalogStr(%b_Catalog, strnum, defaultstr) :
- defaultstr);
-
- return((strlen(str) > 0) ? str, defaultstr);
- }
-
- Najoptymalniej byîoby aby takie zachowanie byîo opcjonalne i domyôlnie
- wyîâczone. Jednakûe brak takiej moûliwoôci jest znacznie mniej dotkliwy
- niû puste gadûety.
-
- * Funkcja OpenCatalog() szuka katalogu który chcesz otworzyê najpierw w
- "PROGDIR:Catalogs/" a dopiero potem w "LOCALE:Catalogs/", zatem jeôli
- nie masz naprawdë powaûnych powodów ku temu, nie instaluj katalogów
- od swojego programu w tym ostatnim.
-
-
- 8. W nastëpnym odcinku...
-
- Za miesiâc ostatnia czëôê z naszego mini cykly, w której, dla odmiany
- przyjrzymy sië sië programom od oczyma tîumacza oraz nauczymy nasz
- przykîadowy programik jëzyków obcych (czyli pokaûemy po co naprawdë to
- wszystko nam byîo potrzebne).
-